/**
 * HTTP缓存管理器
 * @description 提供HTTP请求缓存功能，支持TTL过期机制、缓存统计、自动清理等功能
 * @author 系统开发团队
 * @version 1.0.0
 */

/**
 * HTTP缓存管理器类
 * @description 管理HTTP请求的缓存数据，提供设置、获取、删除、清理等操作
 */
class HttpCacheManager {
  /** 缓存存储Map，key为缓存键，value为缓存数据对象 */
  private cache = new Map<string, { data: any; timestamp: number; ttl: number }>()

  /**
   * 设置缓存
   * @description 将数据存储到缓存中，包含时间戳和TTL信息
   * @param {string} key 缓存键
   * @param {any} data 要缓存的数据
   * @param {number} ttl 缓存生存时间（毫秒），默认5分钟
   * @example
   * httpCacheManager.set('user_123', { name: 'John' }, 60000)
   */
  set(key: string, data: any, ttl: number = 5 * 60 * 1000): void {
    this.cache.set(key, {
      data,
      timestamp: Date.now(),
      ttl
    })
  }

  /**
   * 获取缓存
   * @description 从缓存中获取数据，如果缓存过期则自动删除并返回null
   * @param {string} key 缓存键
   * @returns {any | null} 缓存的数据，如果不存在或已过期则返回null
   * @example
   * const userData = httpCacheManager.get('user_123')
   * if (userData) {
   *   console.log('从缓存获取到用户数据:', userData)
   * }
   */
  get(key: string): any | null {
    const cached = this.cache.get(key)
    if (!cached) {
      return null
    }

    const now = Date.now()
    if (now - cached.timestamp > cached.ttl) {
      // 缓存已过期，删除并返回null
      this.cache.delete(key)
      return null
    }

    return cached.data
  }

  /**
   * 删除缓存
   * @description 删除指定的缓存项
   * @param {string} key 缓存键
   * @returns {boolean} 是否成功删除
   * @example
   * const deleted = httpCacheManager.delete('user_123')
   * console.log('缓存删除成功:', deleted)
   */
  delete(key: string): boolean {
    return this.cache.delete(key)
  }

  /**
   * 清除所有缓存
   * @description 清空所有缓存数据
   * @example
   * httpCacheManager.clear()
   */
  clear(): void {
    this.cache.clear()
  }

  /**
   * 清理过期缓存
   * @description 遍历所有缓存项，删除已过期的缓存
   * @example
   * httpCacheManager.cleanup()
   */
  cleanup(): void {
    const now = Date.now()
    for (const [key, value] of this.cache.entries()) {
      if (now - value.timestamp > value.ttl) {
        this.cache.delete(key)
      }
    }
  }

  /**
   * 获取缓存统计信息
   * @description 返回当前缓存的统计信息，包括缓存数量和所有缓存键
   * @returns {object} 包含size（缓存数量）和keys（缓存键数组）的对象
   * @example
   * const stats = httpCacheManager.getStats()
   * console.log('缓存数量:', stats.size)
   * console.log('缓存键:', stats.keys)
   */
  getStats(): { size: number; keys: string[] } {
    return {
      size: this.cache.size,
      keys: Array.from(this.cache.keys())
    }
  }
}

// ==================== 单例实例 ====================

/** HTTP缓存管理器单例实例 */
export const httpCacheManager = new HttpCacheManager()

// ==================== 缓存装饰器 ====================

/**
 * 缓存装饰器
 * @description 为类方法添加缓存功能的装饰器，自动缓存方法调用结果
 * @param {number} ttl 缓存生存时间（毫秒），默认5分钟
 * @returns {Function} 装饰器函数
 * @example
 * class UserService {
 *   @cacheable(60000)
 *   async getUser(id: number) {
 *     // 方法实现
 *   }
 * }
 */
export function cacheable(ttl: number = 5 * 60 * 1000) {
  return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
    const method = descriptor.value

    descriptor.value = async function (...args: any[]) {
      // 生成缓存键：方法名_参数JSON字符串
      const key = `${propertyName}_${JSON.stringify(args)}`
      const cached = httpCacheManager.get(key)
      
      // 如果缓存存在，直接返回缓存数据
      if (cached) {
        return cached
      }

      // 执行原方法并缓存结果
      const result = await method.apply(this, args)
      httpCacheManager.set(key, result, ttl)
      
      return result
    }
  }
}

// ==================== 缓存工具函数 ====================

/**
 * 缓存工具函数集合
 * @description 提供常用的缓存操作工具函数
 */
export const cacheUtils = {
  /**
   * 生成缓存键
   * @description 根据前缀和参数生成唯一的缓存键
   * @param {string} prefix 缓存键前缀
   * @param {any} params 参数对象
   * @returns {string} 生成的缓存键
   * @example
   * const key = cacheUtils.generateKey('user', { id: 123, type: 'profile' })
   * // 返回: 'user_{"id":123,"type":"profile"}'
   */
  generateKey(prefix: string, params: any): string {
    return `${prefix}_${JSON.stringify(params)}`
  },

  /**
   * 设置API缓存
   * @description 为API请求设置缓存，使用URL作为缓存键的一部分
   * @param {string} url API请求URL
   * @param {any} data 要缓存的数据
   * @param {number} ttl 缓存生存时间（毫秒），默认10分钟
   * @example
   * cacheUtils.setApiCache('/api/users', userList, 300000)
   */
  setApiCache(url: string, data: any, ttl: number = 10 * 60 * 1000): void {
    const key = `api_${url}`
    httpCacheManager.set(key, data, ttl)
  },

  /**
   * 获取API缓存
   * @description 获取API请求的缓存数据
   * @param {string} url API请求URL
   * @returns {any | null} 缓存的数据，如果不存在或已过期则返回null
   * @example
   * const cachedData = cacheUtils.getApiCache('/api/users')
   * if (cachedData) {
   *   console.log('从缓存获取到API数据:', cachedData)
   * }
   */
  getApiCache(url: string): any | null {
    const key = `api_${url}`
    return httpCacheManager.get(key)
  },

  /**
   * 清除API缓存
   * @description 清除API相关的缓存，可以清除指定URL的缓存或所有API缓存
   * @param {string} url 可选的API请求URL，如果不提供则清除所有API缓存
   * @example
   * // 清除指定URL的缓存
   * cacheUtils.clearApiCache('/api/users')
   * 
   * // 清除所有API缓存
   * cacheUtils.clearApiCache()
   */
  clearApiCache(url?: string): void {
    if (url) {
      // 清除指定URL的缓存
      const key = `api_${url}`
      httpCacheManager.delete(key)
    } else {
      // 清除所有API缓存
      const stats = httpCacheManager.getStats()
      stats.keys.forEach(key => {
        if (key.startsWith('api_')) {
          httpCacheManager.delete(key)
        }
      })
    }
  }
} 